#ifndef SATORY_H
#define SATORY_H
#include <QtCore/qobject.h>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QTcpServer>
#include <QDataStream>
#include "tools.h"
#include "json/json.h"
#include "Crypter.h"
#include "Dream.h"
#include <QSslSocket>

#include "Requests.h"
class Sync
{
    list<RequestTypes> mActions;

    class ForbidList: public list<RequestTypes>
    {
      public:
        ForbidList& operator<<(RequestTypes f);
    };
    typedef map<RequestTypes,ForbidList > RulesMap;
    RulesMap mRules;
    typedef map<RequestTypes,list<RequestTypes> >::iterator RulesIter;
    static Sync* mInstance;
    Sync(){};
    ~Sync(){};
public:
    static void Create();
    static void Free();
    static Sync* GetInstance(){return mInstance;};
    static ForbidList& AddRule(RequestTypes state);
    static bool AddState(RequestTypes state);
    static void RemoveState(RequestTypes state);
};
struct ChatKey
{
    DataBlock encKey,signKey,encKeyForMe;
};
struct RSAKey
{
    DataBlock cipher,sign;
    bool isInit;
};


class Satory:public QObject
{
    Q_OBJECT
    QSslSocket* mSocket;
    quint32 mBlockSize;
    bool isConnected;
    static Satory* mInstance;

    map<long,BaseRequest*> mRequests;
    Satory();
    ~Satory();
    Crypter mCrypter;
    std::string userId,mSessionId;
    int mRequestCounter;


    enum ErrorCode{INCORRECT_PASSWORD,NO_KEYS_FOUND};

    RSAKey publicKey,privateKey;

    bool LoadKey(QString pass,ErrorCode &error);
    bool CreateKeys(DataBlock &pbc,DataBlock &pbs,DataBlock &prc,DataBlock &prs,DataBlock &pr_enc,QString pass);

    list<Dream*> mDreams;
 public:

    BaseRequest* GetTopRequest();

    void SetName(std::string name);
    std::string GetName(){return userId;}
    void SaveDreamKey(const std::string& user,const std::string& key,const std::string& type);
    Dream* GetDream(QString name);
    Dream* MakeDream(QString name);
    RSAKey& GetMyKey();
    void InitDataFolder();
    void ReceiveNotification(Json::Value root);
    QString GetAppPath();
    static Satory* GetInstance();
    static void Create();
    static void Free();
    void InitRoster(QString name);
    void ResetRSA();
    void SaveKey(const std::string& key);
    bool SendMessage(const std::string& st);
    bool Register(QString id,QString email,QString pass,bool store);
    bool ResetKey(QString emailcode,QString id,QString pass,bool store);
    bool Login(QString id,QString pass);
    bool PublicKeyGet(QString userId);
    bool PrivateKeyGet(QString emailcode,QString user);
    bool Verify(QString id);
    bool AskAuth(QString user,ChatKey& key,QString message="");
    bool ConfirmAuth(QString user,ChatKey& key,QString message="");
    bool DeleteAuth(QString user);
    bool SendMessage(QString user,QString message,quint64 counter);
    bool MessageMarkRead(QString user,QString messageid);
    bool HistoryGet(QString userId,int skip);
    bool ChatKeyGet(QString userId);

    bool UserProfileGet(QString userId);
    bool UserUpdateProfile(QString profile);
private slots:
    void OnRetry();
    void OnReset();
    void OnConnect();
    void OnDisconnect();
    void OnReceiveDataBlock();
    void OnError(QAbstractSocket::SocketError socketError);
//signals :
   // void RegisterSucceed(bool success);
    public slots:
//    void OnKeyArrived(QString name);



};

#endif // SATORY_H
